/**
 * Fill metadataStore with metadata, crafted by hand using
 * Breeze Labs: breeze.metadata.helper.js
 * @see http://www.breezejs.com/documentation/metadata-by-hand
 */
(function(angular) {
    'use strict';

    angular.module("app").factory( 'metadata',  ['breeze', factory] );

    function factory(breeze) {
        setNamingConvention();
        return {
            fillStore: fillStore
        };
        /////////////////////
        function setNamingConvention() {
            // Translate certain zza property names between MongoDb names and client names
            var convention = new breeze.NamingConvention({
                serverPropertyNameToClient: function(serverPropertyName) {
                    switch (serverPropertyName) {
                        case '_id':   return 'id';
                        case 'qty':   return 'quantity';
                        case 'optionId':   return 'productOptionId';
                        case 'sizeId':   return 'productSizeId';
                        case 'items':   return 'orderItems';
                        case 'options':   return 'orderItemOptions';
                        default: return serverPropertyName;
                    }
                },
                clientPropertyNameToServer: function(clientPropertyName) {
                    switch (clientPropertyName) {
                        case 'id':   return '_id';
                        case 'quantity':   return 'qty';
                        case 'productOptionId':   return 'optionId';
                        case 'productSizeId':   return 'sizeId';
                        case 'orderItems':   return 'items';
                        case 'orderItemOptions':   return 'options';
                        default: return clientPropertyName;
                    }
                }
            });
            convention.setAsDefault();
        }

        function fillStore(store){

            // Using Breeze Labs: breeze.metadata.helper.js
            // https://github.com/IdeaBlade/Breeze/blob/master/Breeze.Client/Scripts/Labs/breeze.metadata-helper.js
            // The helper reduces data entry by applying common conventions
            // and converting common abbreviations (e.g., 'type' -> 'dataType')

            // 'None' (client-generated) is the default key generation strategy for this app
            var keyGen = breeze.AutoGeneratedKeyType.None;

            // namespace of the corresponding classes on the server
            var namespace = 'Zza.Model';

            var helper = new breeze.config.MetadataHelper(namespace, keyGen);

            /*** Convenience fns and vars ***/

            // addType - make it easy to add the type to the store using the helper
            var addType = function (type) { helper.addTypeToStore(store, type); };

            // DataTypes
            var DT = breeze.DataType;
            var BOOL = DT.Boolean;
            var DATE = DT.DateTime;
            var DECIMAL = DT.Decimal;
            var LUID = DT.Int32; // "Lookup" Id
            var ID = DT.MongoObjectId; // Root entity Id

            addAddress();
            addCustomer();
            addOrder();
            addOrderItem();
            addOrderItemOption();
            addOrderStatus();
            addProduct();
            addProductOption();
            addProductSize();

            function addAddress() {
                addType({
                    name: 'Address',
                    isComplexType: true,
                    dataProperties: {
                        street: { max: 100 },
                        city:   { max: 100 },
                        state:  { max: 2 },
                        zip:    { max: 10 }
                    }
                });
            }
            function addCustomer() {
                addType({
                    name: 'Customer',
                    dataProperties: {
                        id:        { type: ID },
                        firstName: { max: 50 },
                        lastName:  { max: 50 },
                        phone:     { max: 100 },
                        email:     { max: 255 },
                        address:   { complex: 'Address'}
                    },
                    navigationProperties: {
                        orders: {type: 'Order', hasMany: true } // nav in cache; not in Mongo!
                    }
                });
            }
            function addOrder() {
                addType({
                    name: 'Order',
                    dataProperties: {
                        id:        { type: ID },
                        customerId:{ type: ID, required: true },
                        name:      { max: 50, required: true },
                        statusId:  { type: LUID, required: true, default: 1 },//default is 'Ordered'
                        status:    { max: 20, required: true },
                        ordered:   { type: DATE, required: true, default: "2014-01-01T08:00:00Z"},
                        phone:     { max: 100 },
                        delivered:      { type: DATE },
                        deliveryCharge: { type: DECIMAL, required: true, default: 0 },
                        deliveryAddress:{ complex: 'Address'},
                        itemsTotal:     { type: DECIMAL, required: true, default: 0 },
                        orderItems:     { complex: 'OrderItem', hasMany: true }
                    },
                    navigationProperties: {
                        customer: 'Customer',
                        orderStatus: {type: 'OrderStatus', fk: 'statusId'}
                    }
                });
            }
            function addOrderItem() {
                addType({
                    name: 'OrderItem',
                    isComplexType: true,
                    dataProperties: {
                        productId:     { type: LUID, required: true, default: 0 },
                        name:          { max: 50, required: true },
                        type:          { max: 50, required: true },
                        productSizeId: { type: LUID, required: true, default: 0 },
                        size:          { max: 50, required: true },
                        quantity:      { type: DT.Int32, required: true, default: 1 },
                        unitPrice:     { type: DECIMAL, required: true, default: 0 },
                        totalPrice:    { type: DECIMAL, required: true, default: 0 },
                        instructions:  { max: 255 },
                        orderItemOptions: { complex: 'OrderItemOption', hasMany: true }
                    }
                });
            }
            function addOrderItemOption() {
                addType({
                    name: 'OrderItemOption',
                    isComplexType: true,
                    dataProperties: {
                        productOptionId: { type: LUID, required: true, default: 0 },
                        name:            { max: 50, required: true },
                        quantity:        { type: DT.Int32, required: true, default: 1 },
                        price:           { type: DECIMAL, required: true, default: 0 }
                    }
                });
            }
            function addOrderStatus() {
                addType({
                    name: 'OrderStatus',
                    dataProperties: {
                        id:   { type: LUID },
                        name: { max: 50, required: true }
                    }
                });
            }
            function addProduct() {
                addType({
                    name: 'Product',
                    dataProperties: {
                        id:             { type: LUID },
                        type:           { max: 20, required: true },
                        name:           { max: 50, required: true },
                        description:    { max: 255 },
                        image:          { max: 50 }, // image name
                        hasOptions:     { type: BOOL, required: true },
                        isPremium:      { type: BOOL, required: true },
                        isVegetarian:   { type: BOOL, required: true },
                        withTomatoSauce:{ type: BOOL, required: true },
                        sizeIds:        { type: LUID, hasMany: true }
                    }
                });
            }
            function addProductOption() {
                addType({
                    name: 'ProductOption',
                    dataProperties: {
                        id:             { type: LUID },
                        type:           { max: 20, required: true },
                        name:           { max: 50, required: true },
                        factor:         { max: 255 },
                        productTypes:   { hasMany: true }
                    }
                });
            }
            function addProductSize() {
                addType({
                    name: 'ProductSize',
                    dataProperties: {
                        id:           { type: LUID },
                        type:         { max: 20, required: true },
                        name:         { max: 50, required: true },
                        price:        { type: DECIMAL, required: true, default: 0 },
                        premiumPrice: { type: DECIMAL },
                        toppingPrice: { type: DECIMAL },
                        isGlutenFree: { type: BOOL }
                    }
                });
            }
        }
    }

}( this.angular ));